package com.gengzp.rpc.proxy;

import com.gengzp.rpc.annotation.RpcServiceClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.stereotype.Component;
import reactor.util.annotation.NonNull;

import java.lang.reflect.Field;

/**
 * @ClassName RpcProxyProcessor
 * @Description rpc框架代理处理器（通过FactoryBean注册代理）
 * @Author gengzp
 * @Date 2025/8/21 17:40
 */
@Component
public class RpcProxyProcessor implements BeanDefinitionRegistryPostProcessor, BeanFactoryAware {

    private static final Logger logger = LoggerFactory.getLogger(RpcProxyProcessor.class);

    private BeanFactory beanFactory;

    @Override
    public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        // 1.获取所有已注册的 bean 定义
        String[] beanDefinitionNames = registry.getBeanDefinitionNames();

        // 2.循环处理所有的 bean
        for (String beanName : beanDefinitionNames) {
            Class<?> beanClass = beanFactory.getType(beanName);
            if (beanClass == null) {
                continue;
            }

            // 取出 bean 中声明的成员变量, 依次进行处理
            Field[] declaredFields = beanClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                // (1).获取成员变量的接口类型, 只有远程服务的接口 (带有 @RpcServiceClient 注解) 才进行处理
                Class<?> interfaceClass = declaredField.getType();
                if (!interfaceClass.isInterface()) {
                    continue;
                }
                RpcServiceClient rpcServiceClient = interfaceClass.getAnnotation(RpcServiceClient.class);
                if (rpcServiceClient == null) {
                    continue;
                }

                // (2).定义远程调用接口的 bean 名称（使用接口全限定名，确保唯一）
                String rpcServiceBeanName = interfaceClass.getName(); // 例如：com.gengzp.api.SysUserRemoteService

                // (3).检查是否已经注册过
                if (registry.containsBeanDefinition(rpcServiceBeanName)) {
                    continue;
                }

                // (4).创建 RpcServiceFactoryBean 的 bean 定义（由工厂类负责创建代理）
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RpcServiceFactoryBean.class);
                // 向 FactoryBean 的构造函数传入参数：接口类型、服务名、BeanFactory
                builder.addConstructorArgValue(interfaceClass); // 第一个参数：接口.class
                builder.addConstructorArgValue(rpcServiceClient.serviceName()); // 第二个参数：服务名
                builder.addConstructorArgValue(beanFactory); // 第三个参数：BeanFactory

                // (5).注册 FactoryBean 的 bean 定义到 IOC 容器中（工厂会在需要时创建代理对象）
                registry.registerBeanDefinition(rpcServiceBeanName, builder.getBeanDefinition());

                logger.info("远程调用接口 {} 的代理工厂Bean注册成功, 对应的服务名: {}",
                        interfaceClass.getName(), rpcServiceClient.serviceName());
            }
        }
    }

}